package uk.ac.ebi.pride.tools.pap.rest;

import org.apache.log4j.Logger;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.Properties;
import java.net.URL;

/**
 * @author Richard Cote
 * @author Florian Reisinger
 *         Date: 18-Feb-2009
 * @since 0.1
 */
public class PapRestServiceImpl extends HttpServlet {

    private static final Logger log = Logger.getLogger(PapRestServiceImpl.class);

    private static Properties props = null;
    private static final String CONFIG_INIT_PARAM = "config";
    public static final int MAX_NUMBER_TO_SEARCH = 1;


    public void init(ServletConfig servletConfig) throws ServletException {
        super.init(servletConfig);

        if (props == null) {

            String configFile = servletConfig.getInitParameter(CONFIG_INIT_PARAM);

            if (configFile != null) {
                try {
                    URL url = getServletContext().getResource(configFile);

                    // If the config isn't in the servlet context, try the class loader
                    // which allows the config files to be stored in a jar
                    if (url == null) {
                        url = getClass().getResource(configFile);
                    }
                    if (url == null) {
                        log.error("No configuration found for REST Service: " + configFile);
                        throw new ServletException("No configuration found for REST Service: " + configFile);
                    }

                    props = new Properties();
                    props.load(url.openStream());
                    log.warn("REST servlet configured.");
                    log.debug(props.toString());

                } catch (IOException ioe) {
                    props = null;
                    log.error(ioe.getMessage(), ioe);
                    throw new ServletException("Error during REST Service configuration: " + ioe.getMessage(), ioe);
                }

            } else {
                throw new ServletException("No configuration file specified for REST Service.");
            }
        }
    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // http://www.ebi.ac.uk/pride/accessionGenerator/rest/getPrideExpAccessions?count=3
//        System.out.println("servlet path: " + request.getServletPath());   //  /rest
//        System.out.println("context path: " + request.getContextPath());   //  /pride/accessionGenerator
//        System.out.println("request uri : " + request.getRequestURI());    //  /pride/accessionGenerator/rest/getPrideExpAccessions
//        System.out.println("path info   : " + request.getPathInfo());      //  /getPrideExpAccessions
//        System.out.println("path transl.: " + request.getPathTranslated());//  null

        String requestType = request.getPathInfo();

        if (requestType != null) {
            if (props != null) {
                String handlerClassName = props.getProperty(requestType);
                if (handlerClassName != null) {
                    try {
                        Class handlerClass = Class.forName(handlerClassName);
                        PapRestRequestHandler processor = (PapRestRequestHandler) handlerClass.newInstance();
                        log.debug("Got instance of processor.");
                        processor.executeRequest(request, response);
                    } catch (ClassNotFoundException cnfe) {
                        log.error(cnfe.getMessage(), cnfe);
                        throw new ServletException("No handler class available to process request: " + cnfe.getMessage(), cnfe);
                    } catch (ClassCastException cce) {
                        log.error(cce.getMessage(), cce);
                        throw new ServletException("Class " + handlerClassName + " does not implement the required PapRestRequestHandler interface.");
                    } catch (IllegalAccessException iae) {
                        log.error(iae.getMessage(), iae);
                        throw new ServletException("Class " + handlerClassName + " does not allow such access.");
                    } catch (InstantiationException ie) {
                        log.error(ie.getMessage(), ie);
                        throw new ServletException("Class " + handlerClassName + " does could not be instantiated.");
                    }
                } else {
                    log.error("No handler class defined for request type: " + requestType);
                    throw new ServletException("No handler class defined for request type: " + requestType);
                }
            } else {
                log.error("REST Servlet improperly configured!");
                throw new ServletException("REST Servlet improperly configured!");
            }
        } else {
            log.error("No request type defiled for REST processor");
            throw new ServletException("No request type defiled for REST processor");
        }

    }

}